# Copyright (C) 2006,2007  Stephane Alnet
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
# 

#
# For more information visit http://carrierclass.net/
#

use strict; use warnings;

package CCNCore::Collection;
use base qw( Jifty::Collection );

sub unlimit()
{
    my $self = shift;
    
    $self->SUPER::unlimit();
    $self->limit_to_active();
    $self->limit_to_authorized();
}

=pod
    Simply redefine limit_to_active() to do nothing if the Model does not
    use CCNCore::Mixin::Active.
    See ChangeSetCollection, ChangeSetValuesCollection.
=cut

sub limit_to_active()
{
    my $self = shift;
    $self->limit(column => 'is_active', value => 'TRUE');
}

sub _associated_record
{
    my $self = shift;
    
    unless(exists $self->{_associated_record})
    {
        my $record_class = $self->record_class;
        $self->{_associated_record} = new $record_class ( handle => $self->_handle );
    }

    return $self->{_associated_record};
}

sub _column_names
{
    my $self = shift;

    unless(exists $self->{_column_names})
    {
        $self->{_column_names} = [map {$_->name} ($self->_associated_record->columns)];
    }

    return @{$self->{_column_names}};
}

sub limit_to_authorized()
{
    my $self = shift;
    
    my $table = $self->table;

    # has_column (and _columns_in_db) do not work at least with SQLite on an empty table.
    my @columns = $self->_column_names;

    if( grep { $_ eq 'owner' } @columns)
    {
        # Normally we only apply plain, direct ownership.
        $self->_owner();
    }
    else
    {
        my $current_table = $table;
        my $current_alias = 'main';
        my $current_column = 'owner';
        my @authorize_via = $self->_associated_record->authorize_via();
        while(@authorize_via)
        {
            my $column = shift @authorize_via;
            my $table  = shift @authorize_via;

            $current_alias = $self->new_alias($current_table);

            # $(this). = $alias.$column
            my $user = $self->join(
                type => 'left',
                alias1 => $current_alias, column1 => $column,
                table2 => $table, column2 => 'id',
            );
            $current_table = $table;
            $current_column = $column;
        }
        $self->_owner(alias => $current_alias,column => $current_column);
    }
}

# Limit to cases where $alias.$column is owner.
sub _owner
{
    my $self = shift;
    my %args = (
        alias => 'main',
        column => 'owner',
        @_        
    );

    # $(user).web_group = $alias.$column
    my $user = $self->join(
        type => 'left',
        alias1 => $args{alias}, column1 => $args{column},
        table2 => 'user', column2 => 'web_group',
    );
    # $(user).id = current_user
    $self->limit(
        leftjoin => $user, column => 'id',
        value => $self->current_user->id
    );
    # $(usergroups).the_group = $alias.$column
    my $user_groups = $self->join(
        type => 'left',
        alias1 => $args{alias}, column1 => $args{column},
        table2 => 'user_groups', column2 => 'the_group',
    );
    # $(usergroups).id = current_user
    $self->limit(
        leftjoin => $user_groups, column => 'the_user',
        value => $self->current_user->id
    );

}

# Limit to cases where $alias.$column is the parent of the owner.
sub _parent
{
    my $self = shift;
    my %args = (
        alias => 'main',
        column => 'owner',
        @_        
    );

    # $(group).id = $alias.$column
    my $group = $self->join(
        type => 'left',
        alias1 => $args{alias}, column1 => $args{column},
        table2 => 'groups', column2 => 'id',
    );
    
    # $(group).parent is owner
    $self->_owner( alias => $group, column => 'parent' );
}


1;